package network

import (
	"time"

	"github.com/TarsCloud/TarsGo/tars"
	"github.com/TarsCloud/TarsGo/tars/util/conf"
	"github.com/panjf2000/gnet/v2"
	"github.com/wzh200x/gateServer/network/codec"
)

// GateGNetServer 是一个gnet服务器实现
type GateGNetServer struct {
	*gnet.BuiltinEventEngine

	Eng           gnet.Engine
	ConnMgr       *ConnectionManager
	addr          string
	multicore     bool
	loadBalancing gnet.LoadBalancing
	numEventLoop  int
	tick          time.Duration
	tcpKeepAlive  time.Duration
	tcpNoDelay    gnet.TCPSocketOpt
}

// NewGateGNetServer 创建一个新的GateGNetServer
func NewGateGNetServer(sConf *conf.Conf) *GateGNetServer {
	addr := "tcp://" + sConf.GetStringWithDef("server/gnet<addr>", "0.0.0.0:12138")
	return &GateGNetServer{
		ConnMgr:       NewConnectionManager(),
		addr:          addr,
		multicore:     true,
		loadBalancing: gnet.LeastConnections, // 最少连接负载均衡
		numEventLoop:  0,                     // 0表示自动根据CPU核数创建事件循环
		tick:          time.Second,           // 定时器触发间隔
		tcpKeepAlive:  time.Second * 30,      // 保持连接的时间间隔
		tcpNoDelay:    gnet.TCPNoDelay,       // 是否禁用Nagle算法 Nagle 算法会缓冲小数据包合并发送，减少网络报文数，但增加延迟。禁用后（NoDelay=true）会立即发送数据，降低延迟。 游戏类关闭
	}
}

// OnBoot 当服务器启动时调用
func (gs *GateGNetServer) OnBoot(eng gnet.Engine) (action gnet.Action) {
	tars.GetLogger("").Infof("gnet server is listening on %s (multi-core: %t, event-loops: %d)", gs.addr, gs.multicore, gs.numEventLoop)
	gs.Eng = eng
	return
}

// OnOpen 当一个新连接打开时调用
func (gs *GateGNetServer) OnOpen(c gnet.Conn) (out []byte, action gnet.Action) {
	gs.ConnMgr.AddConnection(c)
	tars.GetLogger("").Infof("new connection from %s, current connections: %d", c.RemoteAddr().String(), gs.ConnMgr.Count())
	return
}

// OnClose 当一个连接关闭时调用
func (gs *GateGNetServer) OnClose(c gnet.Conn, err error) gnet.Action {
	codec := c.Context().(*codec.Codec)
	c.SetContext(nil)
	gs.ConnMgr.RemoveConnection(codec.ConnectId)
	if err != nil {
		tars.GetLogger("").Infof("connection from %s closed with error: %v, current connections: %d", c.RemoteAddr().String(), err, gs.ConnMgr.Count())
	} else {
		tars.GetLogger("").Infof("connection from %s closed, current connections: %d", c.RemoteAddr().String(), gs.ConnMgr.Count())
	}
	return gnet.None
}

// OnTick 当服务器定时器触发时调用
func (gs *GateGNetServer) OnTick() (delay time.Duration, action gnet.Action) {
	// 在这里可以添加定时任务，例如检查连接心跳等
	delay = gs.tick
	return
}

// OnTraffic 当服务器接收到数据时调用
func (gs *GateGNetServer) OnTraffic(c gnet.Conn) (action gnet.Action) {
	// 在这里处理接收到的数据
	// 准备转发数据
	codec := c.Context().(*codec.Codec)
	if codec.ReadBufferBytes(c) == gnet.Close {
		return gnet.Close
	}
	if codec.Buf.Len() <= 0 {
		return gnet.None
	}
	packets, err := codec.Decode()
	if err != nil {
		tars.GetLogger("").Errorf("OnTraffic decode err %v", err)
		return gnet.Close
	}
	packets.Iterator(func(k int, v interface{}) bool {
		// if p, ok := v.(*message.Packet); ok {
		// 	connectManager.PhoenixManagerConnect().AddPackets(codec.ConnectId, p)
		// }
		return true
	})
	// data, err := c.Read()
	// if err != nil {
	// 	log.Printf("failed to read data from %s: %v", c.RemoteAddr().String(), err)
	// 	return gnet.Close
	// }
	// log.Printf("received data from %s: %s", c.RemoteAddr().String(), string(data))
	// 可以在这里添加数据转发逻辑
	return
}

// Start 启动gnet服务器
func (gs *GateGNetServer) Start() error {
	return gnet.Run(gs, gs.addr,
		gnet.WithMulticore(gs.multicore),
		gnet.WithLoadBalancing(gs.loadBalancing),
		gnet.WithNumEventLoop(gs.numEventLoop),
		gnet.WithTicker(true),
		gnet.WithTCPKeepAlive(gs.tcpKeepAlive),
		gnet.WithTCPNoDelay(gs.tcpNoDelay),
	)
}
